--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit 4d25e17f65784f1fe55d77a4a29c450a1bc1aeee
Parents : a42e1b8
Author : Mark Qvist <bc7291552be7a58f361522990465165c>
Date : 2026-05-04T01:18:37+02:00
Added table rendering to micron
Changes
3 files changed, 84 insertions(+), 1 deletions(-)
Diff
diff --git a/nomadnet/ui/textui/Guide.py b/nomadnet/ui/textui/Guide.py
index ddb2cb3..03becdd 100644
--- a/nomadnet/ui/textui/Guide.py
+++ b/nomadnet/ui/textui/Guide.py
@@ -1302,6 +1302,30 @@ Here is `F00f`_`[a more visible link`72914442a3689add83a09a767963f57c:/page/inde
When links like these are displayed in the built-in browser, clicking on them or activating them using the keyboard will cause the browser to load the specified URL.
+>Tables
+
+You can include rendered tables by enclosing them in \\`t tags. Optionally, you can also specify alignment and max rendering width by adding these properties to the opening \\`t tag, like \\`tc30. Here's an example:
+
+`Faaa
+`=
+`t
+| Name | Price | Qty |
+| ---- | :---: | --: |
+| `F3a3Apple`f | Free | `!5`! |
+| Orange | Ask, nicely | 3 |
+`t
+`=
+``
+
+The above markup produces the following table:
+
+`t
+| Name | Price | Qty |
+| ---- | :---: | --: |
+| `F3a3Apple`f | Free | `!5`! |
+| Orange | Ask, nicely | 3 |
+`t
+
>Fields & Requests
Nomad Network let's you use simple input fields for submitting data to node-side applications. Submitted data, along with other session variables will be available to the node-side script / program as environment variables.
diff --git a/nomadnet/ui/textui/MicronParser.py b/nomadnet/ui/textui/MicronParser.py
index 6327cb8..75fa13b 100644
--- a/nomadnet/ui/textui/MicronParser.py
+++ b/nomadnet/ui/textui/MicronParser.py
@@ -5,6 +5,7 @@ import time
import RNS
from urwid.util import is_mouse_press
from urwid.text_layout import calc_coords
+from RNS.Utilities.rngit.util import MarkdownToMicron
DEFAULT_FG_DARK = "ddd"
DEFAULT_FG_LIGHT = "222"
@@ -31,12 +32,17 @@ SYNTH_SPECS = {}
SECTION_INDENT = 2
INDENT_RIGHT = 1
+MAX_TABLE_WIDTH = 100
def default_state(fg=None, bg=None):
if fg == None: fg = SELECTED_STYLES["plain"]["fg"]
if bg == None: bg = DEFAULT_BG
state = {
"literal": False,
+ "table_mode": False,
+ "table_buffer": [],
+ "table_align": None,
+ "table_maxwidth": MAX_TABLE_WIDTH,
"depth": 0,
"fg_color": fg,
"bg_color": bg,
@@ -134,6 +140,29 @@ def parse_partial(line):
except Exception as e: return None
+def render_table(lines, state, url_delegate):
+ if len(lines) < 2: return None
+ if state["table_maxwidth"]: max_width = state["table_maxwidth"]
+ else: max_width = MAX_TABLE_WIDTH
+ if state["table_align"]: align = state["table_align"]
+ else: align = None
+
+ converter = MarkdownToMicron(max_width=max_width)
+ micron_lines = converter.format_table_raw(lines, align=align)
+
+ widgets = []
+ for line in micron_lines:
+ # Disable table mode to avoid recursion
+ was_table_mode = state["table_mode"]
+ state["table_mode"] = False
+
+ line_widgets = parse_line(line, state, url_delegate)
+ state["table_mode"] = was_table_mode
+
+ if line_widgets: widgets.extend(line_widgets)
+
+ return widgets if widgets else None
+
def parse_line(line, state, url_delegate):
pre_escape = False
if len(line) > 0:
@@ -161,6 +190,36 @@ def parse_line(line, state, url_delegate):
elif first_char == "#":
return None
+ # Check for tables
+ if line.startswith("`t"):
+ line = line[2:]
+ align = line[0] if len(line) and line[0] in ["l", "c", "r"] else None
+ max_width = None
+ if align: line = line[1:]
+ if len(line):
+ try: max_width = int(line)
+ except: pass
+
+ if state["table_mode"]:
+ widgets = render_table(state["table_buffer"], state, url_delegate)
+ state["table_mode"] = False
+ state["table_buffer"] = []
+ state["table_align"] = None
+ state["table_maxwidth"] = MAX_TABLE_WIDTH
+ return widgets
+
+ else:
+ state["table_mode"] = True
+ state["table_buffer"] = []
+ state["table_align"] = align
+ state["table_maxwidth"] = max_width
+ return None
+
+ # Buffer the line if in table mode
+ if state["table_mode"]:
+ state["table_buffer"].append(line)
+ return None
+
# Check for partials
elif line.startswith("`{"):
return parse_partial(line[2:])
diff --git a/setup.py b/setup.py
index bbdd4f9..a880c39 100644
--- a/setup.py
+++ b/setup.py
@@ -31,6 +31,6 @@ setuptools.setup(
entry_points= {
'console_scripts': ['nomadnet=nomadnet.nomadnet:main']
},
- install_requires=["rns>=1.2.0", "lxmf>=0.9.6", "urwid>=2.6.16", "qrcode"],
+ install_requires=["rns>=1.2.1", "lxmf>=0.9.6", "urwid>=2.6.16", "qrcode"],
python_requires=">=3.7",
)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────